/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or ( at your option ) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#include "m_system.h"
#include "m_system_cpp.h"
#include "m_database.h"

namespace DB 
{
	namespace MetaContact
	{
		INT			SubCount	( HANDLE hMetaContact );
		INT			SubDefNum	( HANDLE hMetaContact );
		HANDLE	Sub				( HANDLE hMetaContact, INT idx );

		BOOLEAN IsSub			( HANDLE hContact );
		HANDLE	GetMeta		( HANDLE hContact );

	} /* namespace MetaContact */

	/**
	 * This namespace contains all functions used to access
	 * or modify contacts in the database.
	 **/
	namespace Contact
	{
		LPTSTR	DisplayName	( HANDLE hContact );
		LPSTR		Proto				( HANDLE hContact );
/*		LPTSTR	ProtoName		( HANDLE hContact );*/

		INT			GetCount		();
		HANDLE	FindFirst		();
		HANDLE	FindNext		( HANDLE hContact );

		HANDLE	Add					();
		INT			Delete			( HANDLE hContact );

		DWORD		WhenAdded		( DWORD dwUIN, LPCSTR szBaseProto );

	} /* namespace Contact */

	namespace Module
	{
		VOID		Delete	( HANDLE hContact, LPCSTR szModule );
		BOOLEAN IsEmpty	( HANDLE hContact, LPCSTR szModule );

		BOOLEAN IsMeta				( LPCSTR szModule );
		BOOLEAN IsMetaAndScan	( LPCSTR szModule );

	} /* namespace Module */

	/**
	 * This namespace defines all functions used to read values from the database.
	 **/
	namespace Setting
	{
		/**
		 * This namespace defines all functions used to read values from the database.
		 * The values are written to a DBVARIANT structure with the desired string coding.
		 **/
		INT									Get					( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv, const BYTE nType );
		static __inline INT GetAsIs			( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv ) {	return Get( hContact, szModule, szSetting, dbv, 0 ); }
		static __inline INT GetAString	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv ) {	return Get( hContact, szModule, szSetting, dbv, DBVT_ASCIIZ ); }
		static __inline INT GetWString	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv ) {	return Get( hContact, szModule, szSetting, dbv, DBVT_WCHAR ); }
		static __inline INT GetUString	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DBVARIANT *dbv ) {	return Get( hContact, szModule, szSetting, dbv, DBVT_UTF8 ); }

		INT									GetEx					( HANDLE hContact, LPCSTR szModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv, const BYTE nType );
		static __inline INT GetAsIsEx			( HANDLE hContact, LPCSTR szModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetEx( hContact, szModule, szProto, szSetting, dbv, 0 ); }
		static __inline INT GetAStringEx	( HANDLE hContact, LPCSTR szModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetEx( hContact, szModule, szProto, szSetting, dbv, DBVT_ASCIIZ ); }
		static __inline INT GetWStringEx	( HANDLE hContact, LPCSTR szModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetEx( hContact, szModule, szProto, szSetting, dbv, DBVT_WCHAR ); }
		static __inline INT GetUStringEx	( HANDLE hContact, LPCSTR szModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetEx( hContact, szModule, szProto, szSetting, dbv, DBVT_UTF8 ); }

		WORD								GetCtrl					( HANDLE hContact, LPCSTR szModule, LPCSTR szSubModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv, const BYTE nType );
		static __inline INT GetAsIsCtrl			( HANDLE hContact, LPCSTR szModule, LPCSTR szSubModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetCtrl( hContact, szModule, szSubModule, szProto, szSetting, dbv, 0 ); }
		static __inline INT GetAStringCtrl	( HANDLE hContact, LPCSTR szModule, LPCSTR szSubModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetCtrl( hContact, szModule, szSubModule, szProto, szSetting, dbv, DBVT_ASCIIZ ); }
		static __inline INT GetWStringCtrl	( HANDLE hContact, LPCSTR szModule, LPCSTR szSubModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetCtrl( hContact, szModule, szSubModule, szProto, szSetting, dbv, DBVT_WCHAR ); }
		static __inline INT GetUStringCtrl	( HANDLE hContact, LPCSTR szModule, LPCSTR szSubModule, LPCSTR szProto, LPCSTR szSetting, DBVARIANT *dbv ) { return GetCtrl( hContact, szModule, szSubModule, szProto, szSetting, dbv, DBVT_UTF8 ); }

		INT									GetStatic				( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, LPSTR szValue, INT cchValue );

		/**
		 * This namespace defines all functions used to read values from the database.
		 * The values are converted to the desired type and returned.
		 **/
		BYTE									GetByte		( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, BYTE errorValue );
		static __inline BYTE	GetByte		( LPCSTR szModule, LPCSTR szSetting, BYTE errorValue ) { return GetByte( NULL, szModule, szSetting, errorValue ); }
		static __inline BYTE	GetByte		( LPCSTR szSetting, BYTE errorValue ) { return GetByte( MODNAME, szSetting, errorValue ); }

		WORD									GetWord		( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, WORD errorValue );
		static __inline WORD	GetWord		( LPCSTR szModule, LPCSTR szSetting, WORD errorValue ) { return GetWord( NULL, szModule, szSetting, errorValue ); }
		static __inline WORD	GetWord		( LPCSTR szSetting, WORD errorValue ) { return GetWord( MODNAME, szSetting, errorValue ); }

		DWORD									GetDWord	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DWORD errorValue );
		static __inline DWORD	GetDWord	( LPCSTR szModule, LPCSTR szSetting, DWORD errorValue ) { return GetDWord( NULL, szModule, szSetting, errorValue ); }
		static __inline DWORD	GetDWord	( LPCSTR szSetting, DWORD errorValue ) { return GetDWord( MODNAME, szSetting, errorValue ); }

		LPSTR		GetAString		( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting );
		LPWSTR	GetWString		( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting );
	
		/**
		 * This namespace defines all functions used to write values to the database.
		 **/
		INT			WriteVariant	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, const DBVARIANT *dbv );

		INT									WriteByte		( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, BYTE value );
		static __inline INT	WriteByte		( LPCSTR szModule, LPCSTR szSetting, BYTE value ) { return WriteByte( NULL, szModule, szSetting, value ); }
		static __inline INT	WriteByte		( LPCSTR szSetting, BYTE value ) { return WriteByte( MODNAME, szSetting, value ); }

		INT									WriteWord		( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, WORD value );
		static __inline INT	WriteWord		( LPCSTR szModule, LPCSTR szSetting, WORD value ) { return WriteWord( NULL, szModule, szSetting, value ); }
		static __inline INT	WriteWord		( LPCSTR szSetting, WORD value ) { return WriteWord( MODNAME, szSetting, value ); }

		INT									WriteDWord	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, DWORD value );
		static __inline INT	WriteDWord	( LPCSTR szModule, LPCSTR szSetting, DWORD value ) { return WriteDWord( NULL, szModule, szSetting, value ); }
		static __inline INT	WriteDWord	( LPCSTR szSetting, DWORD value ) { return WriteDWord( MODNAME, szSetting, value ); }

		INT									WriteAString	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, LPSTR value );
		static __inline INT	WriteAString	( LPCSTR szModule, LPCSTR szSetting, LPSTR value ) { return WriteAString( NULL, szModule, szSetting, value ); }
		static __inline INT	WriteAString	( LPCSTR szSetting, LPSTR value ) { return WriteAString( MODNAME, szSetting, value ); }

		INT									WriteWString	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, LPWSTR value );
		static __inline INT	WriteWString	( LPCSTR szModule, LPCSTR szSetting, LPWSTR value ) { return WriteWString( NULL, szModule, szSetting, value ); }
		static __inline INT	WriteWString	( LPCSTR szSetting, LPWSTR value ) { return WriteWString( MODNAME, szSetting, value ); }

		INT									WriteUString	( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting, LPSTR value );
		static __inline INT	WriteUString	( LPCSTR szModule, LPCSTR szSetting, LPSTR value ) { return WriteUString( NULL, szModule, szSetting, value ); }
		static __inline INT	WriteUString	( LPCSTR szSetting, LPSTR value ) { return WriteUString( MODNAME, szSetting, value ); }
		
#ifdef _UNICODE
	#define GetTString			GetWString
	#define GetTStringEx		GetWStringEx
	#define GetTStringCtrl	GetWStringCtrl
	#define WriteTString		WriteWString
#else
	#define GetTString			GetAString
	#define GetTStringEx		GetAStringEx
	#define GetTStringCtrl	GetAStringCtrl
	#define WriteTString		WriteAString
#endif

		/**
		 * misc operations
		 **/
		BOOLEAN	Exists				( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting );
		INT			Delete				( HANDLE hContact, LPCSTR szModule, LPCSTR szSetting );
		VOID		DeleteArray		( HANDLE hContact, LPCSTR szModule, LPCSTR pszFormat, INT iStart );
		INT			Resident			( LPCSTR szSetting, const bool enabled );

	} /* namespace WriteSetting */

	namespace Variant
	{
		INT ConvertString	( DBVARIANT* dbv, const BYTE destType );
		INT ToString			( DBVARIANT* dbv, const BYTE destType );
		INT	Free					( DBVARIANT* dbv );

	} /* namespace Convert */

	namespace Event
	{
		HANDLE	FindFirst				( HANDLE hContact );
		HANDLE	FindLast				( HANDLE hContact );
		HANDLE	FindNext				( HANDLE hEvent );
		HANDLE	FindPrev				( HANDLE hEvent );

		INT			GetInfo					( HANDLE hEvent, DBEVENTINFO *dbei );
		INT			GetInfoWithData	( HANDLE hEvent, DBEVENTINFO *dbei );

		DWORD		GetTime					( HANDLE hEvent );
		DWORD		BlobSizeOf			( HANDLE hEvent );

		BOOLEAN Exists					( HANDLE hContact, HANDLE& hDbExistingEvent, DBEVENTINFO *dbei );

	} /* namespace Events */

	/**
	 * enumerating
	 **/
	class CEnumList : public ::LIST<CHAR>
	{
		static INT EnumProc( LPCSTR pszName, DWORD ofsModuleName, LPARAM lParam );
		static INT EnumSettingsProc( LPCSTR pszName, LPARAM lParam );

		static INT CompareProc( LPCSTR p1, LPCSTR p2 );
		
	public:
		CEnumList();
		~CEnumList();

		LPSTR Insert( LPCSTR str );

		INT EnumModules();
		INT EnumSettings( HANDLE hContact, LPCSTR szModule );
	};

} /* namespace DB */